﻿using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using System;
using System.Threading.Tasks;

namespace JNPF.Extensions.Authorizations.Policys
{
    /// <summary>
    /// 权限授权处理器
    /// </summary>
    public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
    {
        /// <summary>
        /// 验证方案提供对象
        /// </summary>
        public IAuthenticationSchemeProvider Schemes { get; set; }
        //private readonly IRoleModulePermissionServices _roleModulePermissionServices;
        private readonly IHttpContextAccessor _accessor;

        /// <summary>
        /// 构造函数注入
        /// </summary>
        /// <param name="schemes"></param>
        /// <param name="roleModulePermissionServices"></param>
        /// <param name="accessor"></param>
        public PermissionHandler(IAuthenticationSchemeProvider schemes, IHttpContextAccessor accessor)
        {
            _accessor = accessor;
            Schemes = schemes;
        }

        // 重写异步处理程序
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
        {
            var httpContext = _accessor.HttpContext;
            throw new NotImplementedException();
        }
        //protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
        //{
        //    var httpContext = _accessor.HttpContext;
        //    // 获取系统中所有的角色和菜单的关系集合
        //    if (!requirement.Permissions.Any())
        //    {
        //        var data = await _roleModulePermissionServices.RoleModuleMaps();
        //        var list = new List<PermissionItem>();
        //        // ids4和jwt切换
        //        // ids4
        //        if (Permissions.IsUseIds4)
        //        {
        //            list = (from item in data
        //                    where item.IsDeleted == false
        //                    orderby item.Id
        //                    select new PermissionItem
        //                    {
        //                        Url = item.Module?.LinkUrl,
        //                        Role = item.Role?.Id.ObjToString(),
        //                    }).ToList();
        //        }
        //        // jwt
        //        else
        //        {
        //            list = (from item in data
        //                    where item.IsDeleted == false
        //                    orderby item.Id
        //                    select new PermissionItem
        //                    {
        //                        Url = item.Module?.LinkUrl,
        //                        Role = item.Role?.Name.ObjToString(),
        //                    }).ToList();
        //        }
        //        requirement.Permissions = list;
        //    }

        //    if (httpContext != null)
        //    {
        //        var questUrl = httpContext.Request.Path.Value.ToLower();

        //        // 整体结构类似认证中间件UseAuthentication的逻辑，具体查看开源地址
        //        // https://github.com/dotnet/aspnetcore/blob/master/src/Security/Authentication/Core/src/AuthenticationMiddleware.cs
        //        httpContext.Features.Set<IAuthenticationFeature>(new AuthenticationFeature
        //        {
        //            OriginalPath = httpContext.Request.Path,
        //            OriginalPathBase = httpContext.Request.PathBase
        //        });

        //        // Give any IAuthenticationRequestHandler schemes a chance to handle the request
        //        // 主要作用是: 判断当前是否需要进行远程验证，如果是就进行远程验证
        //        var handlers = httpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
        //        foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
        //        {
        //            if (await handlers.GetHandlerAsync(httpContext, scheme.Name) is IAuthenticationRequestHandler handler && await handler.HandleRequestAsync())
        //            {
        //                context.Fail();
        //                return;
        //            }
        //        }


        //        //判断请求是否拥有凭据，即有没有登录
        //        var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
        //        if (defaultAuthenticate != null)
        //        {
        //            var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name);

        //            // 是否开启测试环境
        //            var isTestCurrent = Appsettings.app(new string[] { "JNPF_App", "AppSettings", "UseLoadTest" }).ObjToBool();

        //            //result?.Principal不为空即登录成功
        //            if (result?.Principal != null || isTestCurrent)
        //            {

        //                if (!isTestCurrent) httpContext.User = result.Principal;

        //                // 获取当前用户的角色信息
        //                var currentUserRoles = new List<string>();
        //                // ids4和jwt切换
        //                // ids4
        //                if (Permissions.IsUseIds4)
        //                {
        //                    currentUserRoles = (from item in httpContext.User.Claims
        //                                        where item.Type == "role"
        //                                        select item.Value).ToList();
        //                }
        //                else
        //                {
        //                    // jwt
        //                    currentUserRoles = (from item in httpContext.User.Claims
        //                                        where item.Type == requirement.ClaimType
        //                                        select item.Value).ToList();
        //                }

        //                var isMatchRole = false;
        //                var permisssionRoles = requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role));
        //                foreach (var item in permisssionRoles)
        //                {
        //                    try
        //                    {
        //                        if (Regex.Match(questUrl, item.Url?.ObjToString().ToLower())?.Value == questUrl)
        //                        {
        //                            isMatchRole = true;
        //                            break;
        //                        }
        //                    }
        //                    catch (Exception)
        //                    {
        //                        // ignored
        //                    }
        //                }

        //                //验证权限
        //                if (currentUserRoles.Count <= 0 || !isMatchRole)
        //                {
        //                    context.Fail();
        //                    return;
        //                }

        //                var isExp = false;
        //                // ids4和jwt切换
        //                // ids4
        //                if (Permissions.IsUseIds4)
        //                {
        //                    isExp = (httpContext.User.Claims.SingleOrDefault(s => s.Type == "exp")?.Value) != null && DateHelper.StampToDateTime(httpContext.User.Claims.SingleOrDefault(s => s.Type == "exp")?.Value) >= DateTime.Now;
        //                }
        //                else
        //                {
        //                    // jwt
        //                    isExp = (httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) != null && DateTime.Parse(httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) >= DateTime.Now;
        //                }
        //                if (isExp)
        //                {
        //                    context.Succeed(requirement);
        //                }
        //                else
        //                {
        //                    context.Fail();
        //                    return;
        //                }
        //                return;
        //            }
        //        }
        //        //判断没有登录时，是否访问登录的url,并且是Post请求，并且是form表单提交类型，否则为失败
        //        if (!(questUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) && (!httpContext.Request.Method.Equals("POST") || !httpContext.Request.HasFormContentType)))
        //        {
        //            context.Fail();
        //            return;
        //        }
        //    }

        //    //context.Succeed(requirement);
        //}
    }
}
